﻿using System;
using System.Web;
using System.Linq;
using System.Text;
using System.Web.Caching;
using System.Web.Routing;
using System.Web.Security;
using System.Configuration;
using System.Collections.Generic;

using Tencent.OA.App;
using Tencent.OA.ACM.App;
using Tencent.OA.ACM.Entity;

using Tencent.OA.Common.Web.Security;
using Tencent.OA.Framework.Organization;
using Tencent.OA.Framework.RightWay.Proxy;
using Tencent.OA.Framework.RightWay.Entity;

#if TOFV2
using TOF_RightClient = Tencent.OA.Framework.RightWay.Proxy.RightClient;
#else
using TOF_RightClient = Tencent.OA.Framework.RightWay.Proxy.RightV3Client;
#endif

namespace Tencent.OA.ACM.App
{
    /// <summary>
    /// 用户权限相关类
    /// </summary>
    public class Authentication
    {
        /// <summary>
        /// SESSION登录标识
        /// </summary>
        public static readonly string SessionKey = "SESSION_STAFF";

        /// <summary>
        /// 获取当前登录用户的功能操作集合。
        /// </summary>
        /// <param name="staffID"></param>
        /// <returns></returns>
        internal static List<Operation> GetStaffOperation(int staffID)
        {
            return TOF_RightClient.GetOperations(MvcApplication.SystemID, staffID);
        }

        public static void RestoreSessionState(HttpContextBase context)
        {
            if (context.Request.IsAuthenticated)
            {
                string userName = context.User.Identity.Name;
                if (context.Session["Session_UserName"] == null || context.Session[SessionKey] == null)
                {
                    BancheStaff staff = new BancheStaff(userName);
                    staff.OperationList = Authentication.GetStaffOperation(staff.Id);

                    context.Session[SessionKey] = staff;
                    context.Session["Session_UserName"] = new Tencent.OA.Framework.Organization.Staff(staff.Id);
                }
            }
        }

        internal static bool SetSignIn(HttpContextBase context, string loginName)
        {
            try
            {
                BancheStaff staff = new BancheStaff(loginName);
                staff.OperationList = Authentication.GetStaffOperation(staff.Id);
                context.Session[SessionKey] = staff;
                context.Session["Session_UserName"] = new Tencent.OA.Framework.Organization.Staff(staff.Id);
                FormsAuthentication.SetAuthCookie(loginName, false);
                return true;
            }
            catch
            {
                return false;
            }            
        }

        internal static void SetSignOut(HttpContextBase context)
        {
            context.Session[SessionKey] = null;
            context.Session["Session_UserName"] = null;
            context.Session.Abandon();

            FormsAuthentication.SignOut();

            PassportAuthentication passport = new PassportAuthentication();
            passport.SignOut(MvcApplication.HomePage);
        }

        /// <summary>
        /// 检查当前用户是否有权限访问。
        /// </summary>
        /// <param name="operateCode">操作代码</param>
        /// <returns>true: 是  false:否</returns>
        public static bool CheckRight(string operateCode)
        {
            return CheckRight(operateCode, BancheStaff.CurrentStaffID);
        }

        /// <summary>
        /// 检查指定用户是否有权限访问。
        /// </summary>
        /// <param name="operateCode">操作代码</param>
        /// <param name="staffId">用户id</param>
        /// <returns>true: 是  false:否</returns>
        public static bool CheckRight(string operateCode, int staffID)
        {
            string cacheKey = staffID + "_OPERATECODES";

            List<Operation> operations;
            if (MvcApplication.LoadCachedData(cacheKey, () => GetStaffOperation(staffID), out operations))
            {
                IEnumerable<Operation> result = operations.Where((o) => o.Code.Equals(operateCode));
                return result.Count<Operation>() > 0;
            }
            return false;
        }

        /// <summary>
        /// 检查当前请求内容是否授权
        /// </summary>
        /// <returns></returns>
        public static bool CheckRequestAuthentication(HttpContext context, RouteData routeData)
        {
            MvcSiteMapProvider provider = (MvcSiteMapProvider)SiteMap.Provider;
            MvcSiteMapNode node = provider.FindControllerActionNode(SiteMap.RootNode, routeData.Values) as MvcSiteMapNode;
            if (node != null && !node.IgnoreRole && !node.IsAccessibleToUser(context))
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 检查当前请求是否忽略权限检查，忽略返回true,否则返回false
        /// </summary>
        /// <param name="context"></param>
        /// <param name="routeData"></param>
        /// <returns></returns>
        public static bool CheckRequestIgnoreAuthentication(HttpContext context, RouteData routeData)
        {
            MvcSiteMapProvider provider = (MvcSiteMapProvider)SiteMap.Provider;
            MvcSiteMapNode node = provider.FindControllerActionNode(SiteMap.RootNode, routeData.Values) as MvcSiteMapNode;
            if (node != null && node.IgnoreRole)
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 在Masterpage中验证权限
        /// </summary>
        /// <param name="context"></param>
        public static void CheckRightOnMasterPage(System.Web.Mvc.ViewContext context)
        {
            bool isAuthen = Authentication.CheckRequestAuthentication(HttpContext.Current, context.RouteData);
            bool ignoreAuth = CheckRequestIgnoreAuthentication(HttpContext.Current, context.RouteData);
            HttpContextBase httpContextBase = new HttpContextWrapper(HttpContext.Current);
            RouteData routeData = RouteTable.Routes.GetRouteData(httpContextBase);
            RequestContext requestContext = new RequestContext(httpContextBase, routeData);

            System.Web.Mvc.UrlHelper url = new System.Web.Mvc.UrlHelper(requestContext);

            //没有查看的权限
            if (!isAuthen && !ignoreAuth)
            {
                context.RequestContext.HttpContext.Response.Redirect(url.Action("AccessDeny", "Home", new { requstPath = HttpUtility.UrlEncode(httpContextBase.Request.RawUrl) }));
            }
        }

    }
}
